﻿using CivitaiAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CivitaiAPI.Utils
{
    public static class ModelInfoExtensions
    {
        static readonly string whiteSpacePattern = @"\s+";
        static readonly Regex whiteSpaceRegex = new Regex(whiteSpacePattern);
        static string RemoveWhiteSpace(string val) => whiteSpaceRegex.Replace(val, " ");

        static readonly string illegalPathPattern = @"[\\\/:\*\?""<>|]";
        static readonly Regex illagalPathRegex = new Regex(illegalPathPattern);
        static readonly char[] defaultTrimChars = { ' ' };
        static string RemoveIllegalPathCharacters(string source, char[] trimChars = null, string replacement = "")
        {
            trimChars = trimChars ?? defaultTrimChars;
            string result = illagalPathRegex.Replace(source, replacement);
            if (trimChars.Length > 0) result = result.Trim(trimChars);
            return result;
        }

        public static bool HasDescription(this ModelInfo model)
        {
            return !string.IsNullOrWhiteSpace(model.description);
        }

        public static string FormatDescriptionText(this ModelInfo model)
        {
            return HTML2Text.Html2Text(model.description.Replace("<br />", "\n").Replace("</p><p>", "\n"));
        }

        public static string FormatName(this ModelInfo model)
        {
            string modelName = RemoveWhiteSpace(RemoveIllegalPathCharacters($"{model.name.Trim(new char[] { ' ', '.' })}"));
            if (modelName.Length > 150)
            {
                modelName = modelName.Substring(0, 150);
            }
            return modelName;
        }

        public static string FormatName(this ModelVersion modelVersion)
        {
            return RemoveWhiteSpace(RemoveIllegalPathCharacters($"{modelVersion.name.Replace(".", "").Trim()}"));
        }

        public static bool HasDescription(this ModelVersion modelVersion)
        {
            return !string.IsNullOrWhiteSpace(modelVersion.description);
        }

        public static string FormatDescriptionText(this ModelVersion modelVersion)
        {
            return $"{FormatTrainedWords(modelVersion)}{HTML2Text.Html2Text(modelVersion.description.Replace("<br />", "\n").Replace("</p><p>", "\n"))}";
        }

        public static string FormatTrainedWords(this ModelVersion modelVersion)
        {
            return $"{(modelVersion.trainedWords != null && modelVersion.trainedWords.Count > 0 ? $"{string.Join("\r\n", modelVersion.trainedWords)}\r\n\r\n" : "")}";
        }

        public static string FormatModelMeta(this ModelInfo model)
        {
            return string.Format("Type: {0}\nID: {1}\nCreator: {2}\nTags: {3}", model.type, model.id, model.creator.username, model.tags != null && model.tags.Count > 0 ? string.Join(", ", model.tags) : "");
        }

        public static string GetSizedImageUrl(this Image img, int width = -1)
        {
            string url = img.url;
            if (url.Contains("/width="))
            {
                string first = url.Substring(0, url.IndexOf("/width="));
                string last = url.Substring(url.LastIndexOf("/"));
                int downloadWidth = width;
                if (width <= 0 || width > img.width)
                {
                    downloadWidth = img.width;
                }
                else if (img.width > img.height)
                {
                    downloadWidth = (int)Math.Round((double)(img.width * width) / img.height);
                }
                else
                {
                    downloadWidth = width;
                }

                url = $"{first}/width={downloadWidth}{last}";
            }
            return url;
        }
    }
}
